package com.vca.service.service.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.vca.common.constants.Constants;
import com.vca.common.exception.VcaException;
import com.vca.common.model.exhibition.Exhibition;
import com.vca.common.model.exhibition.ExhibitionScheduling;
import com.vca.common.model.order.StoreOrder;
import com.vca.common.model.order.StoreOrderInfo;
import com.vca.common.model.user.User;
import com.vca.common.page.CommonPage;
import com.vca.common.request.*;
import com.vca.common.response.AdminHeaderResponse;
import com.vca.common.response.ExhibitionSchedulingAdminByIdResponse;
import com.vca.common.response.ExhibitionSchedulingAdminResponse;
import com.vca.common.utils.DateUtil;
import com.vca.common.utils.PageUtils;
import com.vca.common.utils.VcaUtil;
import com.vca.common.vo.ExcelExOrderInfo;
import com.vca.common.vo.ExcelExSchedulingById;
import com.vca.common.vo.dateLimitUtilVo;
import com.vca.service.dao.exhibition.ExhibitionDao;
import com.vca.service.dao.exhibition.ExhibitionSchedulingDao;
import com.vca.service.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程排课表 服务实现类
 * </p>
 *
 * @author chenBing
 * @since 2022-11-03
 */
@Service
public class ExhibitionSchedulingServiceImpl extends ServiceImpl<ExhibitionSchedulingDao, ExhibitionScheduling> implements ExhibitionSchedulingService {

    @Autowired
    private ExhibitionSchedulingDao dao;

    @Autowired
    private ExhibitionDao exhibitionDao;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private VcaLineUpService vcaLineUpService;

    @Autowired
    private StoreOrderService orderService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private ExhibitionService exhibitionService;

    @Autowired
    private ExportService exportService;

    @Autowired
    private UserService userService;

    @Autowired
    private StoreOrderInfoService orderInfoService;

    /**
     * 展览排课管理
     *
     * @param request
     * @param pageParamRequest
     * @return
     * @author Li
     * @date 2022/11/16 15:06
     */
    @Override
    public PageInfo getAdminList(SchedulingAdminListRequest request, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<ExhibitionScheduling> wrapper = new LambdaQueryWrapper();
        wrapper.eq(ExhibitionScheduling::getIsDeleted, 0);
        if (ObjectUtil.isNotEmpty(request.getKeywords())) {
            List<Integer> ids = exhibitionDao.fuzzySearch(request.getKeywords());
            if (ObjectUtil.isEmpty(ids)) {
                List<ExhibitionSchedulingAdminResponse> exhibitionSchedulingAdminResponses = new ArrayList<>();
                return PageUtils.startPage(exhibitionSchedulingAdminResponses, pageParamRequest.getPage(), pageParamRequest.getLimit());
            }
            wrapper.in(ExhibitionScheduling::getExhibitionId, ids);
        }
        if (ObjectUtil.isNotEmpty(request.getSchedulingStatus())) {
            if (request.getSchedulingStatus().equals(3)) {
                wrapper.eq(ExhibitionScheduling::getIsCancel, 1);
            }
        }
        if (ObjectUtil.isNotEmpty(request.getDateLimit())) {
            getRequestTimeWhere(wrapper, request);
        }
        if (ObjectUtil.isNotEmpty(request.getStatus())) {
            wrapper.eq(ExhibitionScheduling::getStatus, request.getStatus());
        }
        wrapper.orderByDesc(ExhibitionScheduling::getExhibitionId);
        List<ExhibitionScheduling> exhibitionSchedulings = dao.selectList(wrapper);
        List<ExhibitionSchedulingAdminResponse> adminList = new ArrayList<>();
        String nowDate = DateUtil.nowDate("yyyy-MM-dd HH:mm:ss");
        if (ObjectUtil.isNotEmpty(exhibitionSchedulings)) {
            LambdaQueryWrapper<Exhibition> exhibitionWrapper = new LambdaQueryWrapper<>();
            exhibitionWrapper.in(Exhibition::getId, exhibitionSchedulings.stream().map(ExhibitionScheduling::getExhibitionId).collect(Collectors.toList()));
            List<Exhibition> exhibitions = exhibitionDao.selectList(exhibitionWrapper);
            exhibitionSchedulings.forEach(e -> {
                ExhibitionSchedulingAdminResponse response = new ExhibitionSchedulingAdminResponse();
                BeanUtils.copyProperties(e, response);
                if (ObjectUtil.isEmpty(e.getIsCancel())) {
                    response.setSchedulingStatus(DateUtil.getSchedulingStatus(e.getSchedulingDate(), e.getSchedulingStartTime(), e.getSchedulingEndTime()));
                } else {
                    if (e.getIsCancel().equals(1)) {
                        response.setSchedulingStatus(3);
                    } else {
                        response.setSchedulingStatus(DateUtil.getSchedulingStatus(e.getSchedulingDate(), e.getSchedulingStartTime(), e.getSchedulingEndTime()));
                    }
                }
                exhibitions.forEach(exhibition -> {
                    if (e.getExhibitionId().equals(exhibition.getId())) {
                        response.setName(exhibition.getName());
                        response.setCoverImage(exhibition.getCover());
                    }
                });
                adminList.add(response);
            });
        }
        List<ExhibitionSchedulingAdminResponse> filter = adminList;
        if (ObjectUtil.isNotEmpty(request.getSchedulingStatus())) {
            filter = adminList.stream().filter(e -> e.getSchedulingStatus().equals(Integer.valueOf(request.getSchedulingStatus()))).collect(Collectors.toList());
        }
        filter.sort(Comparator.comparing(ExhibitionSchedulingAdminResponse::getSchedulingDate));
        return PageUtils.startPage(filter, pageParamRequest.getPage(), pageParamRequest.getLimit());
    }

    @Override
    public ExcelExSchedulingById getBookingDetail(String id, PageParamRequest pageParamRequest) {
        /**
         * 查找排期数据
         */
        ExhibitionScheduling exhibitionScheduling = getById(id);
        if(exhibitionScheduling == null) {
            throw new VcaException("不存在这个展览排期");
        }
        Exhibition exhibition = exhibitionService.getById(exhibitionScheduling.getExhibitionId());
        if(exhibition == null) {
            throw new VcaException("不存在这个展览");
        }
        String name = exhibition.getName();
        //标题数据
        ExcelExSchedulingById excelExSchedulingById = new ExcelExSchedulingById();
        BeanUtils.copyProperties(exhibitionScheduling, excelExSchedulingById);
        boolean status = exportService.checkExcelStatus(exhibitionScheduling.getSchedulingDate(), exhibitionScheduling.getSchedulingStartTime(), exhibitionScheduling.getSchedulingEndTime());
        excelExSchedulingById.setStatus(status?"已结束":"未开始");
        excelExSchedulingById.setName(exhibition.getName());
        /**
         * 查找核销或待核销的数据
         */
        List<ExcelExOrderInfo> list = new ArrayList();
//        excelExSchedulingById.setList(list);
        LambdaQueryWrapper<StoreOrderInfo> storeOrderInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeOrderInfoLambdaQueryWrapper.eq(StoreOrderInfo::getSchedulingId, id);
        //已核销
        LambdaQueryWrapper<StoreOrder> storeOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        storeOrderLambdaQueryWrapper.and(wrapper -> wrapper.in(StoreOrder::getStatus, Arrays.asList(2, 3)).in(StoreOrder::getType, Arrays.asList(0,1,2,3)).or(wrapper1 -> wrapper1.eq(StoreOrder::getPaid, false).eq(StoreOrder::getStatus, 0)));
        storeOrderLambdaQueryWrapper.eq(StoreOrder::getIsDel, false);
        List<StoreOrder> storeOrderList = orderService.list(storeOrderLambdaQueryWrapper);
        //已核销主订单
        List<String> storeOrderNoList = null;
        if(CollectionUtil.isNotEmpty(storeOrderList)) {
            storeOrderNoList = storeOrderList.stream().map(StoreOrder::getOrderId).collect(Collectors.toList());
        }
        //待核销
//        storeOrderInfoLambdaQueryWrapper.eq(StoreOrderInfo::getStatus, 1);
//        storeOrderInfoLambdaQueryWrapper.eq(StoreOrderInfo::getRefundStatus, 0);
        final List<String> finalStoreOrderNoList = storeOrderNoList;
        if(CollectionUtil.isNotEmpty(finalStoreOrderNoList)) {
            storeOrderInfoLambdaQueryWrapper.and(wrapper->wrapper.eq(StoreOrderInfo::getStatus, 1).eq(StoreOrderInfo::getRefundStatus, 0).or().in(CollectionUtil.isNotEmpty(finalStoreOrderNoList), StoreOrderInfo::getOrderNo, finalStoreOrderNoList));
        }else {
            storeOrderInfoLambdaQueryWrapper.eq(StoreOrderInfo::getStatus, 1).eq(StoreOrderInfo::getRefundStatus, 0);
        }
        List<StoreOrderInfo> storeOrderInfos = orderInfoService.list(storeOrderInfoLambdaQueryWrapper);
        if(CollectionUtil.isNotEmpty(storeOrderInfos)) {
            for (int i = 0; i < storeOrderInfos.size(); i++) {
                StoreOrderInfo storeOrderInfo = storeOrderInfos.get(i);
                ExcelExOrderInfo excelExOrderInfo = new ExcelExOrderInfo();
                BeanUtils.copyProperties(storeOrderInfo, excelExOrderInfo);
                //购买人
                User buyer = userService.getById(storeOrderInfo.getBuyer());
                if(buyer != null) {
                    excelExOrderInfo.setNickname(buyer.getNickname());
                    excelExOrderInfo.setPhone(VcaUtil.maskMobile(buyer.getPhone()));
                    excelExOrderInfo.setEmail(buyer.getEmail());
                }else {
//                    throw new VcaException("不存在该购买人："+storeOrderInfo.getBuyer());
                }
                //主订单
                StoreOrder storeOrder = orderService.getByOrderId(storeOrderInfo.getOrderNo());
                if(storeOrder != null) {
                    //支付渠道
                    if (storeOrder.getUserType() == 1) {
                        excelExOrderInfo.setChannel("后台赠送");
                    } else {
                        excelExOrderInfo.setChannel("微信支付");
                    }
                    //主订单uid
                    if(StringUtils.isBlank(excelExOrderInfo.getNickname()) && storeOrder.getUid() != null) {
                        User user = userService.getById(storeOrder.getUid());
                        if(user != null) {
                            excelExOrderInfo.setNickname(user.getNickname());
                            excelExOrderInfo.setPhone(VcaUtil.maskMobile(user.getPhone()));
                            excelExOrderInfo.setEmail(user.getEmail());
                        }
                    }
                }else {
//                    throw new VcaException("不存在该主订单："+storeOrderInfo.getOrderNo());
                }
                //核销状态
                if(storeOrder != null) {
                    if(storeOrder.getPaid()) {
                        if(storeOrderInfo.getWriteOffClerkId() == null) {
                            excelExOrderInfo.setWriteOffStatus("待核销");
                        }else {
                            excelExOrderInfo.setWriteOffStatus("已核销");
                        }
                    }else {
                        excelExOrderInfo.setWriteOffStatus("待支付");
                    }
                }
                //核销时间
                if(storeOrderInfo.getWriteOffTime() != null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                    excelExOrderInfo.setWriteOffTime(simpleDateFormat.format(storeOrderInfo.getWriteOffTime()));
                }
                list.add(excelExOrderInfo);
            }
        }
        excelExSchedulingById.setPageInfo(CommonPage.restPage(PageUtils.startPage(list, pageParamRequest.getPage(), pageParamRequest.getLimit())));

        return excelExSchedulingById;
    }

    /**
     * 展览排期日历列表
     *
     * @param request
     * @return
     * @author Li
     * @date 2022/11/21 11:19
     */
    @Override
    public List<ExhibitionSchedulingAdminResponse> getCalendarList(SchedulingAdminListRequest request) {
        LambdaQueryWrapper<ExhibitionScheduling> wrapper = new LambdaQueryWrapper();
        if (ObjectUtil.isNotEmpty(request.getKeywords())) {
            wrapper.in(ExhibitionScheduling::getExhibitionId, exhibitionDao.fuzzySearch(request.getKeywords()));
        }
        if (ObjectUtil.isNotEmpty(request.getDateLimit())) {
            getRequestTimeWhere(wrapper, request);
        }
        if (ObjectUtil.isNotEmpty(request.getStatus())) {
            wrapper.eq(ExhibitionScheduling::getStatus, request.getStatus());
        }
        wrapper.orderByDesc(ExhibitionScheduling::getExhibitionId);
        List<ExhibitionScheduling> exhibitionSchedulings = dao.selectList(wrapper);
        List<ExhibitionSchedulingAdminResponse> adminList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(exhibitionSchedulings)) {
            LambdaQueryWrapper<Exhibition> exhibitionWrapper = new LambdaQueryWrapper<>();
            exhibitionWrapper.in(Exhibition::getId, exhibitionSchedulings.stream().map(ExhibitionScheduling::getExhibitionId).collect(Collectors.toList()));
            List<Exhibition> exhibitions = exhibitionDao.selectList(exhibitionWrapper);
            exhibitionSchedulings.forEach(e -> {
                ExhibitionSchedulingAdminResponse response = new ExhibitionSchedulingAdminResponse();
                BeanUtils.copyProperties(e, response);
                response.setSchedulingStatus(DateUtil.getSchedulingStatus(e.getSchedulingDate(), e.getSchedulingStartTime(), e.getSchedulingEndTime()));
                exhibitions.forEach(exhibition -> {
                    if (e.getExhibitionId().equals(exhibition.getId())) {
                        response.setName(exhibition.getName());
                        response.setCoverImage(exhibition.getCover());
                    }
                });
                adminList.add(response);
            });
        }
        List<ExhibitionSchedulingAdminResponse> filter = adminList;
        if (ObjectUtil.isNotEmpty(request.getSchedulingStatus())) {
            filter = adminList.stream().filter(e -> e.getSchedulingStatus().equals(Integer.valueOf(request.getSchedulingStatus()))).collect(Collectors.toList());
        }
        return filter;
    }

    /**
     * 添加展览排期
     *
     * @param request
     * @return
     * @author Li
     * @date 2022/11/21 11:19
     */
    @Override
    public boolean addScheduling(SchedulingAddRequest<ExhibitionSchedulingAddRequest> request) {
        //取出添加排期的展览id
        List<Long> exhibitionId = request.getSchedulingRequests().stream().map(ExhibitionSchedulingAddRequest::getExhibitionId).collect(Collectors.toList());
        //查询展览是否存在
        LambdaQueryWrapper<Exhibition> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Exhibition::getId, exhibitionId.get(0));
        wrapper.eq(Exhibition::getIsDeleted, 0);
        Exhibition exhibition = exhibitionDao.selectOne(wrapper);
        if (ObjectUtil.isEmpty(exhibition)) {
            throw new VcaException("该展览不存在");
        }

        //将排期信息拷贝
        List<ExhibitionScheduling> exhibitionSchedulings = new ArrayList();
        request.getSchedulingRequests().forEach(e -> {
            ExhibitionScheduling exhibitionScheduling = new ExhibitionScheduling();
            BeanUtils.copyProperties(e, exhibitionScheduling);
            List<String> schedulingTime = VcaUtil.stringToArrayStrRegex(e.getSchedulingTime(), "~");
            exhibitionScheduling.setSchedulingStartTime(schedulingTime.get(0));
            exhibitionScheduling.setSchedulingEndTime(schedulingTime.get(1));
            exhibitionScheduling.setStatus(1);
            exhibitionScheduling.setIsCancel(0);
            exhibitionScheduling.setPrice(exhibition.getPrice());
            exhibitionSchedulings.add(exhibitionScheduling);
        });
        boolean sendNotice;
        if (checkSchedulingQuta(exhibitionId.get(0))) {
            sendNotice = true;
        } else {
            sendNotice = false;
        }
        //批量添加
        return transactionTemplate.execute(e -> {
            int a = 0;
            for (ExhibitionScheduling exhibitionScheduling : exhibitionSchedulings) {
                dao.insert(exhibitionScheduling);
                if (checkSchedulingDate(exhibitionScheduling)) {
                    a++;
                }
            }
            if (a > 0 && sendNotice) {
                vcaLineUpService.noticeByMainId(exhibitionId.get(0), Constants.ORDER_TYPE_EXHIBITION);
            }
            return Boolean.TRUE;
        });
    }

    /**
     * 修改展览排期
     *
     * @param request
     * @return
     * @author Li
     * @date 2022/11/21   11:19
     */
    @Override
    public boolean updateScheduling(ExhibitionSchedulingAddRequest request) {
        //查询排期是否存在
        ExhibitionScheduling exhibitionScheduling = checkScheduling(request.getId());
        //将值拷贝并修改
        if (ObjectUtil.isNotEmpty(request.getQuota())) {
            if (request.getQuota() > exhibitionScheduling.getQuota() && checkSchedulingQuta(exhibitionScheduling.getExhibitionId()) && checkSchedulingDate(exhibitionScheduling)) {
                vcaLineUpService.noticeByMainId(exhibitionScheduling.getExhibitionId(), Constants.ORDER_TYPE_EXHIBITION);
            }
            exhibitionScheduling.setQuota(request.getQuota());
        }
        if (ObjectUtil.isNotEmpty(request.getStatus())) {
            exhibitionScheduling.setStatus(request.getStatus());
        }
        return transactionTemplate.execute(e -> {
            dao.updateById(exhibitionScheduling);
            return Boolean.TRUE;
        });
    }

    /**
     * 跟据展览id查询排期
     *
     * @param exhibitionId
     * @return
     * @author Li
     * @date 2022/11/21 09:47
     */
    @Override
    public ExhibitionSchedulingAdminByIdResponse getAdminScheduling(Long exhibitionId) {
        ExhibitionScheduling exhibitionScheduling = checkScheduling(exhibitionId);
        ExhibitionSchedulingAdminByIdResponse response = new ExhibitionSchedulingAdminByIdResponse();
        if (ObjectUtil.isEmpty(exhibitionScheduling.getIsCancel())) {
            response.setSchedulingStatus(DateUtil.getSchedulingStatus(exhibitionScheduling.getSchedulingDate(), exhibitionScheduling.getSchedulingStartTime(), exhibitionScheduling.getSchedulingEndTime()));
        } else {
            if (exhibitionScheduling.getIsCancel().equals(1)) {
                response.setSchedulingStatus(3);
            } else {
                response.setSchedulingStatus(DateUtil.getSchedulingStatus(exhibitionScheduling.getSchedulingDate(), exhibitionScheduling.getSchedulingStartTime(), exhibitionScheduling.getSchedulingEndTime()));
            }
        }
        BeanUtils.copyProperties(exhibitionScheduling, response);

        Exhibition exhibition = exhibitionDao.selectOne(new LambdaQueryWrapper<Exhibition>().eq(Exhibition::getId, exhibitionScheduling.getExhibitionId()));
        if (ObjectUtil.isNotEmpty(exhibition)) {
            response.setPrice(exhibition.getPrice());
            response.setName(exhibition.getName());
            response.setPrice(exhibition.getPrice());
        }
        return response;
    }

    /**
     * 根据展览排期id删除排期
     *
     * @param schedulingId
     * @return
     * @author Li
     * @date 2022/11/21   15:02
     */
    @Override
    public boolean deleteScheduling(Long schedulingId) {
        LambdaQueryWrapper<ExhibitionScheduling> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExhibitionScheduling::getId, schedulingId);
        wrapper.eq(ExhibitionScheduling::getIsDeleted, 0);
        ExhibitionScheduling exhibitionScheduling = dao.selectOne(wrapper);
        if (ObjectUtil.isEmpty(exhibitionScheduling)) {
            throw new VcaException("该排期已被删除");
        }
        exhibitionScheduling.setIsDeleted(1);
        exhibitionScheduling.setStatus(0);
        return transactionTemplate.execute(e -> {
            dao.update(exhibitionScheduling, new LambdaUpdateWrapper<ExhibitionScheduling>().eq(ExhibitionScheduling::getId, schedulingId).set(ExhibitionScheduling::getIsDeleted, 1));
            return Boolean.TRUE;

        });
    }

    /**
     * @return
     * @author Li
     * @date 2022/11/24
     */
    @Override
    public List<AdminHeaderResponse> getHeader(String dateLimit) {
        List<AdminHeaderResponse> responses = new ArrayList<>();
        LambdaQueryWrapper<ExhibitionScheduling> wrapper = new LambdaQueryWrapper();
        wrapper.eq(ExhibitionScheduling::getIsDeleted, 0);
        if (ObjectUtil.isNotEmpty(dateLimit)) {
            getRequestTimeWhere(wrapper, new SchedulingAdminListRequest().setDateLimit(dateLimit));
        }
        List<ExhibitionScheduling> exhibitionSchedulings = dao.selectList(wrapper);
        String nowDate = DateUtil.nowDate("yyyy-MM-dd HH:mm:ss");
        //初始化map
        Map<Integer, Integer> status = new HashMap();
        status.put(0, 0);
        status.put(1, 0);
        status.put(2, 0);
        status.put(3, 0);
        exhibitionSchedulings.forEach(e -> {
            Integer integer = 0;
            if (ObjectUtil.isEmpty(e.getIsCancel())) {
                //动态添加排课状态
                integer = DateUtil.getSchedulingStatus(e.getSchedulingDate(), e.getSchedulingStartTime(), e.getSchedulingEndTime());
            } else {
                if (e.getIsCancel().equals(1)) {
                    integer = 3;
                } else {
                    //动态添加排课状态
                    integer = DateUtil.getSchedulingStatus(e.getSchedulingDate(), e.getSchedulingStartTime(), e.getSchedulingEndTime());
                }
            }

            status.put(integer, status.get(integer) + 1);
        });
        responses.add(new AdminHeaderResponse(exhibitionSchedulings.size(), "全部", null, 4));
        responses.add(new AdminHeaderResponse(status.get(0), "已结束", null, 0));
        responses.add(new AdminHeaderResponse(status.get(1), "进行中", null, 1));
        responses.add(new AdminHeaderResponse(status.get(2), "未开始", null, 2));
        responses.add(new AdminHeaderResponse(status.get(3), "已取消", null, 3));
        return responses;
    }

    /**
     * 上架展览排期预约状态
     *
     * @param exhibitionSchedulingId 展览排期id
     * @return
     * @author Li
     * @date 2022/11/18 15:16
     */
    @Override
    public boolean onShell(Long exhibitionSchedulingId) {
        ExhibitionScheduling exhibitionScheduling = checkScheduling(exhibitionSchedulingId);
        exhibitionScheduling.setStatus(1);
        return transactionTemplate.execute(e -> {
            dao.update(exhibitionScheduling, new LambdaUpdateWrapper<ExhibitionScheduling>().eq(ExhibitionScheduling::getId, exhibitionSchedulingId).set(ExhibitionScheduling::getStatus, 1));
            return Boolean.TRUE;
        });
    }

    /**
     * 下架展览排期预约状态
     *
     * @param exhibitionSchedulingId 展览排期id
     * @return
     * @author Li
     * @date 2022/11/18 15:16
     */
    @Override
    public boolean offShell(Long exhibitionSchedulingId) {
        ExhibitionScheduling exhibitionScheduling = checkScheduling(exhibitionSchedulingId);
        exhibitionScheduling.setStatus(0);
        return transactionTemplate.execute(e -> {
            dao.update(exhibitionScheduling, new LambdaUpdateWrapper<ExhibitionScheduling>().eq(ExhibitionScheduling::getId, exhibitionSchedulingId).set(ExhibitionScheduling::getStatus, 0));
            return Boolean.TRUE;
        });
    }

    /**
     * 跟据展览id查询排期
     *
     * @param exhibitionId
     * @param pageParamRequest
     * @return
     * @author Li
     * @date 2022/11/21 09:47
     */
    @Override
    public PageInfo<ExhibitionSchedulingAdminByIdResponse> getListByExhibition(Long exhibitionId, PageParamRequest pageParamRequest) {
        LambdaQueryWrapper<ExhibitionScheduling> wrapper = new LambdaQueryWrapper();
        wrapper.eq(ExhibitionScheduling::getExhibitionId, exhibitionId);
        wrapper.eq(ExhibitionScheduling::getStatus, 1);
        wrapper.eq(ExhibitionScheduling::getIsDeleted, 0);
        wrapper.eq(ExhibitionScheduling::getIsCancel, 0);
        List<ExhibitionScheduling> exhibitionSchedulings = dao.selectList(wrapper);
        List<ExhibitionSchedulingAdminByIdResponse> responses = new ArrayList<>();
        if (ObjectUtil.isEmpty(exhibitionSchedulings)) {
            PageUtils.startPage(responses, pageParamRequest.getPage(), pageParamRequest.getLimit());
        }

        List<ExhibitionSchedulingAdminByIdResponse> exhibitionSchedulingVos = new ArrayList();
        String day = DateUtil.addDay(new Date(), 2, "yyyy-MM-dd");
        exhibitionSchedulings.forEach(e -> {
            ExhibitionSchedulingAdminByIdResponse schedulingVo = new ExhibitionSchedulingAdminByIdResponse();
            BeanUtils.copyProperties(e, schedulingVo);
            schedulingVo.setSchedulingStatus(DateUtil.getSchedulingStatus(e.getSchedulingDate(), e.getSchedulingStartTime(), e.getSchedulingEndTime()));
            Exhibition exhibition = exhibitionDao.selectOne(new LambdaQueryWrapper<Exhibition>().eq(Exhibition::getId, e.getExhibitionId()));
            schedulingVo.setPrice(exhibition.getPrice());
            //过滤未开始的
            if (schedulingVo.getSchedulingStatus() == 2) {
                exhibitionSchedulingVos.add(schedulingVo);
            }
        });
        responses = exhibitionSchedulingVos.stream().sorted(Comparator.comparing(ExhibitionSchedulingAdminByIdResponse::getQuota).reversed()).collect(Collectors.toList());
        responses.sort(Comparator.comparing(ExhibitionSchedulingAdminByIdResponse::getSchedulingDate));
        return PageUtils.startPage(responses, pageParamRequest.getPage(), pageParamRequest.getLimit());
    }

    /**
     * @param schedulingIds
     * @return boolean
     * @description 批量删除排期
     * @author Li
     * @date 2022/11/29 11:28
     */
    @Override
    public boolean updateAll(List<Long> schedulingIds) {
        List<ExhibitionScheduling> schedulingList = dao.selectList(new LambdaQueryWrapper<ExhibitionScheduling>().in(ExhibitionScheduling::getId, schedulingIds));
        LambdaUpdateWrapper<ExhibitionScheduling> wrapper = new LambdaUpdateWrapper<ExhibitionScheduling>();
        wrapper.set(ExhibitionScheduling::getIsDeleted, 1);
        wrapper.in(ExhibitionScheduling::getId, schedulingIds);
        ExhibitionScheduling exhibitionScheduling = new ExhibitionScheduling();
        exhibitionScheduling.setIsDeleted(1);
        return transactionTemplate.execute(e -> {
            dao.update(exhibitionScheduling, wrapper);
            return Boolean.TRUE;
        });
    }

    /**
     * @param request
     * @return com.vca.common.result.CommonResult
     * @description 取消讲座排期
     * @methodName cancel
     * @author Li
     * @date 2022/12/28 16:14
     */
    @Override
    public boolean cancel(SchedulingCancelRequest request) {
        ExhibitionScheduling exhibitionScheduling = checkScheduling(request.getSchedulingId());
        exhibitionScheduling.setIsCancel(1);
        exhibitionScheduling.setCancellationReasons(request.getReason());
        return transactionTemplate.execute(e -> {
            orderService.cancelActivity(request.getSchedulingId().intValue(), 3);
            dao.updateById(exhibitionScheduling);
            return Boolean.TRUE;
        });
    }

    /**
     * @Description:判断展览排期是否还有空余席位
     * @author:chenbing
     * @date 2023/9/18 16:59
     */
    @Override
    public boolean checkSchedulingQuta(Long mainId) {
        List<ExhibitionScheduling> schedulings = list(new LambdaQueryWrapper<ExhibitionScheduling>()
                .eq(ExhibitionScheduling::getExhibitionId, mainId)
                .eq(ExhibitionScheduling::getIsDeleted, false)
                .eq(ExhibitionScheduling::getIsCancel,0)
                .gt(ExhibitionScheduling::getSchedulingDate, DateUtil.dateToStr(new Date(), Constants.DATE_FORMAT_DATE))
                .gt(ExhibitionScheduling::getSchedulingEndTime, DateUtil.dateToStr(new Date(), "HH:mm")));
        if (schedulings.size() <= 0) {
            return true;
        }
        int quota = schedulings.stream().mapToInt(ExhibitionScheduling::getQuota).sum();
        if (quota <= 0) {
            return true;
        }
        return false;
    }

    /**
     * @Description:判断当前排期似乎否已经过了停止预约的时间
     * @author:chenbing
     * @date 2023/9/19 15:16
     */
    @Override
    public boolean checkSchedulingDate(ExhibitionScheduling exhibitionScheduling) {
        if (exhibitionScheduling == null) {
            return false;
        }
        //TODO：获取展览提前停止预约时间
        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.EXHIBITION_END_ORDER_TIME));
        Date schedulingDate = DateUtil.strToDate(exhibitionScheduling.getSchedulingDate() + " " + exhibitionScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
        if (between >= 0) {
            return false;
        }
        return true;
    }

    private ExhibitionScheduling checkScheduling(Long exhibitionSchedulingId) {
        ExhibitionScheduling exhibitionScheduling = dao.selectById(exhibitionSchedulingId);
        if (ObjectUtil.isEmpty(exhibitionScheduling)) {
            throw new VcaException("该排期已被删除");
        }
        return exhibitionScheduling;
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     */
    private void getRequestTimeWhere(LambdaQueryWrapper<ExhibitionScheduling> queryWrapper, SchedulingAdminListRequest request) {
        if (StringUtils.isNotBlank(request.getDateLimit())) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
            queryWrapper.between(ExhibitionScheduling::getSchedulingDate, dateLimitUtilVo.getStartTime().substring(0, 10), dateLimitUtilVo.getEndTime().substring(0, 10));
        }
    }

}
